const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8079 });

const wsMap = new Map();
const ws2name = new WeakMap();

function handle2Peer(message) {
  peerMessage(message.to, message.data);
}

function peerMessage(name, message) {
  const peerws = wsMap.get(name);
  if (peerws) {
    peerws.send(JSON.stringify(message));
  } else {
    console.log('no peer exist', name);
  }
}

function brodcast(message) {
  for (const ws of wsMap.values()) {
    ws.send(JSON.stringify(message));
  }
}

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    try {
      const msgObject = JSON.parse(message);
      if (msgObject.to === '__server__') {
        const data = msgObject.data;
        if (data.type === 'handShake') {
          wsMap.set(data.name, ws);
          ws2name.set(ws, data.name);
          brodcast({ type: 'allPlayers', players: [...wsMap.keys()] });
        }
      } else {
        handle2Peer(msgObject);
      }
    } catch (err) {
      console.error('parse message error', err);
    }
  });

  ws.on('close', (code, reason) => {
    const name = ws2name.get(ws);
    ws2name.delete(ws);
    if (name) {
      wsMap.delete(name);
    }
    console.log('closed', code, reason);
  });
});
